import fastify from 'fastify'
import { addBot, addGroup, addUser, record } from './util'
import { getRank } from './rank'

type Params = Record<string, string>

const port = 8000
export const app = fastify({})

app.addHook('onRequest', async (_, reply) => {
	reply.header('Access-Control-Allow-Origin', '*')
})

class ArgError extends Error {
	constructor(message: string) {
		super(message)
		this.name = 'ArgError'
	}
}

app.post('/record', async (req, reply) => {
	let code = 200
	let msg = 'success'
	try {
		let {
			user_id,
			user_name,
			group_id,
			group_name,
			bot_type,
			bot_name,
			bot_id,
			app,
			plugin_name: plugin,
			platform,
			time = Date.now()
		} = <Params>req.body
		user_name = user_name ?
			user_name.replace(/[^\u4e00-\u9fa5，。！a-zA-Z]/g, '')
			: '匿名'
		user_id = (user_id + '').replace(/([^\w]|-).*/, '')
		if (!user_id)
			throw new ArgError('userid错误')
		if (!user_name || !bot_name || !plugin)
			throw new ArgError('请求错误')
		console.log(user_name, user_id, bot_name, plugin, group_id)
		const p = [
			addUser(user_id, user_name),
			addBot(bot_id, bot_name, bot_type, platform)
		]
		if (group_id) {
			p.push(addGroup(group_id, group_name))
		}
		await Promise.all(p)
		await record(user_id, group_id, bot_id, app, plugin, time)
	} catch (err) {
		if (err instanceof ArgError) {
			code = 400
		} else {
			code = 500
		}
		msg = err.message
	}
	reply.status(code).send({
		code,
		msg
	})
})

app.get('/', (_, reply) => {
	reply.header('Content-Type', 'text/plain')
	reply.header('Content-Security-Policy', "default-src 'self'")
	return 'Hello, world!'
})

app.get('/rank/:type', async (req, reply) => {
	const type = (<Params>req.params).type
	const query = <Params>req.query
	const {
		plugin = '',
		platform = ''
	} = query
	let start = +query.start || 0
	let end = +query.end || Date.now()
	let code = 200
	let msg = 'success'
	let data: any = null
	try {
		if (!type)
			throw new ArgError('请求错误')
		data = await getRank(type, plugin ? plugin.split(',') : [],
			platform ? platform.split(',') : [], start, end)
	} catch (err) {
		if (err instanceof ArgError) {
			code = 400
		} else {
			code = 500
		}
		msg = err.message
	}
	reply.status(code).send({
		code,
		msg,
		data
	})
})

try {
	const addr = await app.listen({ port })
	console.log(`Server listening at ${addr}`)
} catch (err) {
	app.log.error(err)
	process.exit(1)
}

